﻿''' <summary>
''' Public Enumerationto make keeing track of Assignment visibility (all, overdue, today, tomorrow, upcoming) easier
''' </summary>
''' <remarks></remarks>
Public Enum AssignmentVisibility
    all = 0
    overdue = 1
    today = 2
    tomorrow = 3
    upcoming = 4
End Enum

''' <summary>
''' UI control that organizes a list of Assignment controls
''' </summary>
''' <remarks></remarks>
Public Class CollegiateAssignmentList
    Public Property assignments As List(Of Assignment)
    Private currentGuid As String ' For "find" purposes...
    Private taskvisibility As AssignmentVisibility = 0
    Private subjvisibility As String = "All Courses"
    Public WriteOnly Property assignmentVisibility
        Set(ByVal value)
            taskvisibility = value
            hideAssignments()
        End Set
    End Property
    Public WriteOnly Property courseVisibility
        Set(ByVal value)
            subjvisibility = value
            hideAssignments()
        End Set
    End Property

    Sub New()

        ' This call is required by the designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.

    End Sub

    Sub New(ByRef value As List(Of Assignment))

        ' This call is required by the designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        assignments = value

    End Sub

    ''' <summary>
    ''' Creates a new Assignment control, then adds it to the list
    ''' </summary>
    ''' <param name="value">Assignment to base the control off of</param>
    ''' <remarks></remarks>
    Public Sub Add(ByRef value As Assignment)
        ' Add the assignment to the assignment list
        assignments.Add(value)

        ' Create assignment, register it, then add it to the assignments stack
        Dim control As New CollegiateAssignment( _
                value.name,
                value.notes,
                value.parent.name,
                value.parent.color,
                value.endDate,
                value.priority,
                value.complete) _
            With {.Name = value.guid}
        AddHandler control.editAssignment, AddressOf assignmentRaisedEdit
        AddHandler control.deleteAssignment, AddressOf assignmentRaisedDelete
        AddHandler control.changeCompleted, AddressOf assignmentRaisedComplete
        AssignmentsStack.RegisterName(value.guid, control)

        AssignmentsStack.Children.Add(control)

        ' Then create a menu item for it, register it, add it to the menu
        Dim itemEdit As New MenuItem() With _
            {.Header = value.name,
             .Name = value.guid}
        AddHandler itemEdit.Click, AddressOf assignmentMenuRaisedEdit

        Dim itemDelete As New MenuItem() With _
            {.Header = value.name,
             .Name = value.guid}
        AddHandler itemDelete.Click, AddressOf assignmentMenuRaisedDelete

        Assignment.assignmentEditMenu.RegisterName(String.Concat("edit", value.guid), itemEdit)
        Assignment.assignmentEditMenu.Items.Add(itemEdit)
        Assignment.assignmentDeleteMenu.RegisterName(String.Concat("delete", value.guid), itemDelete)
        Assignment.assignmentDeleteMenu.Items.Add(itemDelete)

        AddHandler value.changedParentCourseName, AddressOf Update

        sortAssignments()
        hideAssignments()
    End Sub

    ''' <summary>
    ''' Updates the Assignment control for the given assignment
    ''' </summary>
    ''' <param name="assign">Assignment to find the control for, then update</param>
    ''' <remarks></remarks>
    Public Sub Update(ByRef assign As Assignment)
        Try
            Dim control As CollegiateAssignment = AssignmentsStack.FindName(assign.guid)
            control.AssignmentName = assign.name
            control.AssignmentNotes = assign.notes
            control.priority = assign.priority
            control.DueDate = assign.endDate
            control.completed = assign.complete
            control.CourseColor = assign.parent.color
            control.CourseName = assign.parent.name

            Dim itemEdit As MenuItem = Assignment.assignmentEditMenu.FindName(String.Concat("edit", assign.guid))
            itemEdit.Header = assign.name

            Dim itemDelete As MenuItem = Assignment.assignmentDeleteMenu.FindName(String.Concat("delete", assign.guid))
            itemDelete.Header = assign.name

            sortAssignments()
            hideAssignments()

        Catch exc As Exception
            MessageBox.Show("Problem with the application!:" & vbNewLine & exc.Message)
        End Try
    End Sub

    ''' <summary>
    ''' Sorts the assignments by due date
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub sortAssignments()
        Dim Sorted As Boolean = False
        Do Until Sorted
            Sorted = True
            For i As Integer = 0 To (AssignmentsStack.Children.Count() - 2)
                currentGuid = DirectCast(AssignmentsStack.Children(i), CollegiateAssignment).Name
                Dim currentItem As Date = assignments.Find(AddressOf SameAssignment).endDate
                currentGuid = DirectCast(AssignmentsStack.Children(i + 1), CollegiateAssignment).Name
                Dim nextItem As Date = assignments.Find(AddressOf SameAssignment).endDate
                If currentItem > nextItem Then
                    Dim assignment = AssignmentsStack.Children(i)
                    AssignmentsStack.Children.RemoveAt(i)
                    AssignmentsStack.Children.Insert(i + 1, assignment)
                    Sorted = False
                End If
            Next
        Loop
    End Sub

    ''' <summary>
    ''' Hides assignments based on Assignment Visibility and Course Visibility
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub hideAssignments()
        Select Case taskvisibility
            Case Controls.AssignmentVisibility.all
                For Each item As CollegiateAssignment In AssignmentsStack.Children
                    item.Visibility = Windows.Visibility.Visible
                Next
            Case Controls.AssignmentVisibility.overdue
                For Each item As CollegiateAssignment In AssignmentsStack.Children
                    currentGuid = item.Name

                    If (assignments.Find(AddressOf SameAssignment).endDate.Day < Today.Day) And (Not item.completed) Then
                        item.Visibility = Windows.Visibility.Visible
                    Else
                        item.Visibility = Windows.Visibility.Collapsed
                    End If

                Next
            Case Controls.AssignmentVisibility.today
                For Each item As CollegiateAssignment In AssignmentsStack.Children
                    currentGuid = item.Name
                    item.Visibility = IIf(assignments.Find(AddressOf SameAssignment).endDate.Day <> Today.Day, _
                                          Windows.Visibility.Collapsed, _
                                          Windows.Visibility.Visible)
                Next
            Case Controls.AssignmentVisibility.tomorrow
                For Each item As CollegiateAssignment In AssignmentsStack.Children
                    currentGuid = item.Name
                    item.Visibility = IIf(assignments.Find(AddressOf SameAssignment).endDate.Day <> Today.AddDays(1).Day, _
                                          Windows.Visibility.Collapsed, _
                                          Windows.Visibility.Visible)
                Next
            Case Controls.AssignmentVisibility.upcoming
                For Each item As CollegiateAssignment In AssignmentsStack.Children
                    currentGuid = item.Name
                    item.Visibility = IIf(assignments.Find(AddressOf SameAssignment).endDate.Day <= Today.Day, _
                                          Windows.Visibility.Collapsed, _
                                          Windows.Visibility.Visible)
                Next
        End Select

        If subjvisibility IsNot "All Courses" Then
            For Each item As CollegiateAssignment In AssignmentsStack.Children
                currentGuid = item.Name
                If assignments.Find(AddressOf SameAssignment).parent.name IsNot subjvisibility Then
                    item.Visibility = Windows.Visibility.Collapsed
                End If
            Next
        End If
    End Sub

    ''' <summary>
    ''' Edits the assignment, handles Assignment controls edit event
    ''' </summary>
    ''' <param name="e">Name of assignment that raised the event</param>
    ''' <remarks></remarks>
    Public Sub assignmentRaisedEdit(ByVal e As String)
        currentGuid = e
        Dim current As Assignment = assignments.Find(AddressOf SameAssignment)
        current.Edit()
        Update(current)
    End Sub

    ''' <summary>
    ''' Marks the assignment as complete, handles Assignment controls changedCompleted event
    ''' </summary>
    ''' <param name="e">Assignment name to change complete on</param>
    ''' <param name="value">Boolean value holding whether it was completed or not</param>
    ''' <remarks></remarks>
    Public Sub assignmentRaisedComplete(ByVal e As String, ByVal value As Boolean)
        currentGuid = e
        Dim current As Assignment = assignments.Find(AddressOf SameAssignment)
        current.complete = value
        hideAssignments()
    End Sub

    Public Sub assignmentMenuRaisedEdit(ByVal sender As MenuItem, ByVal e As System.Windows.RoutedEventArgs)
        assignmentRaisedEdit(sender.Name)
    End Sub

    Public Sub assignmentMenuRaisedDelete(ByVal sender As MenuItem, ByVal e As System.Windows.RoutedEventArgs)
        assignmentRaisedDelete(sender.Name)
    End Sub

    ''' <summary>
    ''' Delete the assignment, handles Assignment controls delete event
    ''' </summary>
    ''' <param name="e">Name of assignment that raised the event</param>
    ''' <remarks></remarks>
    Public Sub assignmentRaisedDelete(ByVal e As String)
        currentGuid = e
        Dim value As Assignment = assignments.Find(AddressOf SameAssignment)

        AssignmentsStack.Children.Remove(AssignmentsStack.FindName(currentGuid))
        assignments.Remove(value)
        value.Delete()

        ' Then delete the assignment from both edit and delete menus
        Dim itemEdit As MenuItem = Assignment.assignmentEditMenu.FindName(String.Concat("edit", value.guid))
        Assignment.assignmentEditMenu.Items.Remove(itemEdit)

        Dim itemDelete As MenuItem = Assignment.assignmentDeleteMenu.FindName(String.Concat("delete", value.guid))
        Assignment.assignmentDeleteMenu.Items.Remove(itemDelete)
    End Sub

    ''' <summary>
    ''' Function to help search for an assignment by guid
    ''' </summary>
    ''' <param name="value">The assignment to compare to the one we're looking for</param>
    ''' <returns>Boolean saying whether the supplied assignment is the one being searched for</returns>
    ''' <remarks></remarks>
    Private Function SameAssignment(ByVal value As Assignment) As Boolean

        If value.guid = currentGuid Then
            Return True
        Else
            Return False
        End If
    End Function

End Class